﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Media.Animation;

using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;

using ETRoboConTrakingSystem;

namespace ETRobocon.RaceTraking.GamePresentation
{
    /// <summary>
    /// UserControlTimeCounter.xaml の相互作用ロジック
    /// </summary>
    public partial class UserControlTimeCounter : UserControl, ITimerCounter
    {
        public int CurrentTime
        {
            get
            {
                InternalStopWatch stopWatch = this.Resources["stopWatch"] as InternalStopWatch;
                return stopWatch.CurrentCount;
            }
            set
            {
                InternalStopWatch stopWatch = this.Resources["stopWatch"] as InternalStopWatch;
                stopWatch.CurrentCount = value;
            }
        }

        public UserControlTimeCounter()
        {
            InitializeComponent();
            InternalStopWatch stopWatch = this.Resources["stopWatch"] as InternalStopWatch;
            stopWatch.Owner = this;
            
        }


        public void Start()
        {
            InternalStopWatch stopWatch = this.Resources["stopWatch"] as InternalStopWatch;
            stopWatch.Start();
        }

        public void Stop()
        {
            InternalStopWatch stopWatch = this.Resources["stopWatch"] as InternalStopWatch;
            stopWatch.Stop();
        }

        private Storyboard _storyBoard;

        public void AlertStart()
        {
            if (false)
            {
                NameScope.SetNameScope(this, new NameScope());
                //SolidColorBrush brush = this.borderBG.Background as SolidColorBrush;
                //this.RegisterName("AlertBrush", brush);
                ColorAnimationUsingKeyFrames colorAnimation = new ColorAnimationUsingKeyFrames();
                colorAnimation.Duration = TimeSpan.FromSeconds(16);
                colorAnimation.RepeatBehavior = new RepeatBehavior(1);
                colorAnimation.KeyFrames.Add(
                    new LinearColorKeyFrame(Colors.Red, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(15))));
                colorAnimation.KeyFrames.Add(
                    new LinearColorKeyFrame(Colors.DarkBlue, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(1))));

                Storyboard.SetTargetName(colorAnimation, "AlertBrush");
                Storyboard.SetTargetProperty(colorAnimation, new PropertyPath(SolidColorBrush.ColorProperty));

                _storyBoard = new Storyboard();
                _storyBoard.Children.Add(colorAnimation);

                _storyBoard.Begin(this);
            }
            
        }

        public void AlertStop()
        {
            if (_storyBoard != null)
            {
                _storyBoard.Stop(this);
                _storyBoard.Remove(this);
                _storyBoard = null;
            }
        }

        public void ResetCounter()
        {
            TimeCountFaceInfo info = this.Resources["FaceInfo"] as TimeCountFaceInfo;
            info.Brush = Colors.DarkBlue;
            CurrentTime = 0;
        }
        public delegate int getCurrentTimeCountDelegate();
        private int getCurrentTImeCount()
        {
        //    InternalStopWatch stopWatch = this.Resources["stopWatch"] as InternalStopWatch;
          //  return stopWatch.CurrentCount;
            return InternalStopWatch.CurrentTimeCount;
        }
        public int GetCurrentTimeCount()
        {
            Object ret = this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new getCurrentTimeCountDelegate(getCurrentTImeCount));
            return (int)ret;
        }

        private void EventTrigger_MouseEnter(object sender, MouseEventArgs e)
        {

        }

        #region ITimerCounter Members


        public void SetCurrentCount(int current)
        {
            this.CurrentTime = current;
        }

        #endregion
    }

    public class InternalStopWatch :INotifyPropertyChanged
    {
        private UserControlTimeCounter _owner;

        private int _minH=0;
        private int _minL=0;
        private int _secH=0;
        private int _secL=0;
        private int _secD=0;

        private int currentCount = 0;
        public static int CurrentTimeCount;

        public UserControlTimeCounter Owner
        {
            set { _owner = value; }
            get { return _owner; }
        }


        public int MinH
        {
            get { return _minH; }
            set {
                _minH = value;
                OnPropertyChanged("MinH");
            }
        }
        public int MinL
        {
            get { return _minL; }
            set {
                _minL = value;
                OnPropertyChanged("MinL");
            }
        }
        public int SecH
        {
            get { return _secH; }
            set {
                _secH = value;
                OnPropertyChanged("SecH");
            }
        }
        public int SecL
        {
            get { return _secL; }
            set {
                _secL = value;
                OnPropertyChanged("SecL");
            }
        }
        public int SecD
        {
            get { return _secD; }
            set {
                _secD = value;
                OnPropertyChanged("SecD");
            }
        }

        public int CurrentCount
        {
            get { return currentCount; }
            set
            {
                currentCount = value;
                CurrentTimeCount = value;
                UpdateValues();
                OnPropertyChanged("CurrentCount");
            }

        }

        private System.Threading.Timer myTimer=null;
        private long startTick = 0;
        private bool alerting = false;

        public delegate void UpdateCurrentCountDelegate(int count);
        public void UpdateCurrentCount(int count)
        {
            CurrentCount = count;
            if (alerting == false)
            {
                if (count >= 900)
                {
                    alerting = true;
                    Owner.AlertStart();
                }
            }
        }

        public InternalStopWatch()
        {
        }

        private void UpdateValues()
        {
            SecD = currentCount % 10;
            currentCount /= 10;
            int sec = currentCount % 60;
            SecL = sec % 10;
            sec /= 10;
            SecH = sec;
            currentCount /= 60;
            MinL = currentCount % 10;
            currentCount /= 10;
            MinH = currentCount % 10;
        }

        private long unitTick = 1000000;
        public void Interval(object o)
        {
            long duration = (System.DateTime.Now.Ticks/unitTick) - startTick;
            if (duration <= 1200)
            {
                _owner.Dispatcher.BeginInvoke(
                    System.Windows.Threading.DispatcherPriority.Normal,
                    new UpdateCurrentCountDelegate(UpdateCurrentCount),
                    (int)duration);
            }
            else
            {
                myTimer.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
                myTimer.Dispose();
                myTimer = null;
                alerting = false;
                Owner.AlertStop();
            }
        }

        public void Start()
        {
            if (myTimer == null)
            {
                startTick = System.DateTime.Now.Ticks / unitTick;
                myTimer = new System.Threading.Timer(Interval, this, 100, 100);
            }
        }

        public void Stop()
        {
            if (myTimer != null)
            {
                myTimer.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
                myTimer.Dispose();
                myTimer = null;
                Owner.AlertStop();
            }
        }


        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string name)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(name));
            }
        }

    }
}
